package com.sky.service.impl;

import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.service.OrderService;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private WorkspaceService workspaceService;

    @Override
    public TurnoverReportVO sumByDate(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = dateList(begin, end);
        List<Map<String, BigDecimal>> map = orderMapper.sumByDate(begin,end,Orders.COMPLETED);
        List<BigDecimal> amountList = new ArrayList<>();
        for (int i = 0; i < dateList.size(); i++){
            if(dateList.get(i).isAfter(LocalDate.now())){
                break;
            }
            amountList.add(map.get(i).get("amount"));
        }
        String dateListStr = StringUtils.join(dateList,",");
        String amountListStr = StringUtils.join(amountList,",");
        return TurnoverReportVO.builder()
                .dateList(dateListStr)
                .turnoverList(amountListStr)
                .build();
    }

    @Override
    public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {
        List<Map<String, Long>> mapCompleted = orderMapper.getOrdersStatistics(begin, end, Orders.COMPLETED);
        List<Map<String, Long>> mapAll = orderMapper.getOrdersStatistics(begin, end, null);
        List<Long> completedList = new ArrayList<>();
        List<Long> allList = new ArrayList<>();
        List<LocalDate> dateList = dateList(begin, end);
        for (int i = 0; i < dateList.size(); i++){
            if(dateList.get(i).isAfter(LocalDate.now())){
                break;
            }
            completedList.add(mapCompleted.get(i).get("count"));
            allList.add(mapAll.get(i).get("count"));
        }
        long sumAll = allList.stream().mapToLong(Long::longValue).sum();
        long sumCompleted = completedList.stream().mapToLong(Long::longValue).sum();
        double ratio = (double) sumCompleted / sumAll;

        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .validOrderCountList(StringUtils.join(completedList, ","))
                .orderCountList(StringUtils.join(allList, ","))
                .totalOrderCount((int) sumAll)  // 保持原int类型，强制转换
                .validOrderCount((int) sumCompleted)  // 保持原int类型，强制转换
                .orderCompletionRate(ratio)
                .build();
    }

    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = dateList(begin, end);
        List<Map<String, Long>> totalNewUserList = orderMapper.getNewUserCount(begin, end);
        Long totalNewUser = orderMapper.getTotalUserCount(begin);
        List<Long> newUserList = new ArrayList<>();
        List<Long> totalUserList = new ArrayList<>();
        Long temp = totalNewUser;
        for (int i = 0; i < dateList.size(); i++) {
            if(dateList.get(i).isAfter(LocalDate.now())){
                break;
            }
            if(newUserList.size()>=i){
                newUserList.add(totalNewUserList.get(i).get("count"));
                temp += newUserList.get(i);
            }
            totalUserList.add(temp);
        }
        return UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .build();
    }

    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {
        List<String> nameList = new ArrayList<>(), numberList = new ArrayList<>();
        List<Map<String, Object>> mapList = orderMapper.sumByDish(begin, end , Orders.COMPLETED);
        if(mapList.size()>0){
            for (Map<String, Object> map : mapList) {
                nameList.add((String) map.get("name"));
                numberList.add(map.get("number").toString());
            }
        }
        return SalesTop10ReportVO.builder()
                .nameList(StringUtils.join(nameList, ","))
                .numberList(StringUtils.join(numberList, ","))
                .build();
    }

    @Override
    public void exportBusinessData(HttpServletResponse response){
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);
        BusinessDataVO businessDataVO = workspaceService.getBusinessData(
                LocalDateTime.of(begin, LocalTime.MIN),
                LocalDateTime.of(end, LocalTime.MAX));
        try {
            InputStream oo = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
            Workbook workbook = new XSSFWorkbook(oo);
            Sheet sheet = workbook.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);
            sheet.getRow(3).getCell(2).setCellValue(businessDataVO.getTurnover());
            sheet.getRow(3).getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            sheet.getRow(3).getCell(6).setCellValue(businessDataVO.getNewUsers());
            sheet.getRow(4).getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            sheet.getRow(4).getCell(4).setCellValue(businessDataVO.getUnitPrice());
            for (int i=0 ; i<30 ; i++){
                LocalDate temp = begin.plusDays(i);
                if(temp.isAfter(LocalDate.now())){
                    break;
                }
                BusinessDataVO monthBusinessDataVO = workspaceService.getBusinessData(
                        LocalDateTime.of(temp, LocalTime.MIN),
                        LocalDateTime.of(temp, LocalTime.MAX));
                sheet.getRow(7+i).getCell(1).setCellValue(begin.plusDays(i).toString());
                sheet.getRow(7+i).getCell(2).setCellValue(monthBusinessDataVO.getTurnover());
                sheet.getRow(7+i).getCell(3).setCellValue(monthBusinessDataVO.getValidOrderCount());
                sheet.getRow(7+i).getCell(4).setCellValue(monthBusinessDataVO.getOrderCompletionRate());
                sheet.getRow(7+i).getCell(5).setCellValue(monthBusinessDataVO.getUnitPrice());
                sheet.getRow(7+i).getCell(6).setCellValue(monthBusinessDataVO.getNewUsers());
            }
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.close();
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private List<LocalDate> dateList(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate temp = begin;
        while(!temp.equals(end)) {
            dateList.add(temp);
            temp = temp.plusDays(1);
        }
        dateList.add(end);
        return dateList;
    }
}
